using System.Collections.Generic;
using JQMergeFramework;
using UnityEngine;

public class PositionConvert
{

    /// <summary>
    /// 世界坐标转换为屏幕坐标
    /// </summary>
    /// <param name="worldPoint">屏幕坐标</param>
    /// <returns></returns>
    public static Vector2 WorldPointToScreenPoint(Vector3 worldPoint)
    {
        // Camera.main 世界摄像机
        Vector2 screenPoint = Camera.main.WorldToScreenPoint(worldPoint);
        return screenPoint;
    }

    /// <summary>
    /// 屏幕坐标转换为世界坐标
    /// </summary>
    /// <param name="screenPoint">屏幕坐标</param>
    /// <param name="planeZ">距离摄像机 Z 平面的距离</param>
    /// <returns></returns>
    public static Vector3 ScreenPointToWorldPoint(Vector2 screenPoint, float planeZ)
    {
        // Camera.main 世界摄像机
        Vector3 position = new Vector3(screenPoint.x, screenPoint.y, planeZ);
        Vector3 worldPoint = Camera.main.ScreenToWorldPoint(position);
        return worldPoint;
    }

    
    // RectTransformUtility.WorldToScreenPoint
    // RectTransformUtility.ScreenPointToWorldPointInRectangle
    // RectTransformUtility.ScreenPointToLocalPointInRectangle
    // 上面三个坐标转换的方法使用 Camera 的地方
    // 当 Canvas renderMode 为 RenderMode.ScreenSpaceCamera、RenderMode.WorldSpace 时 传递参数 canvas.worldCamera
    // 当 Canvas renderMode 为 RenderMode.ScreenSpaceOverlay 时 传递参数 null
    
    // UI 坐标转换为屏幕坐标
    public static Vector2 UIPointToScreenPoint(Vector3 worldPoint)
    {
        ///Canvas renderMode 为 RenderMode.ScreenSpaceOverlay 时用这个
        // Camera uiCamera = null;
        // Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(uiCamera, worldPoint);
        // return screenPoint;
        
        // RectTransform：target
        Camera uiCamera = CameraMainControl.I.uiCamera;
        // RectTransformUtility.WorldToScreenPoint(target,worldPoint,uiCamera,out OUTpos);
        Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(uiCamera, worldPoint);
        return screenPoint;
    }

    // UI 坐标转换为屏幕坐标
    public static Vector2 UIPointToScreenPointOverlay(Vector3 worldPoint)
    {
        //Canvas renderMode 为 RenderMode.ScreenSpaceOverlay 时用这个
         Camera uiCamera = null;
         Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(uiCamera, worldPoint);
         return screenPoint;
    }
    
    
    // 屏幕坐标转换为 UGUI 坐标
    public static Vector3 ScreenPointToUIPoint(RectTransform rt, Vector2 screenPoint)
    {
        Vector2 globalMousePos;
        //UI屏幕坐标转换为世界坐标
        Camera uiCamera = CameraMainControl.I.uiCamera;

        // 当 Canvas renderMode 为 RenderMode.ScreenSpaceCamera、RenderMode.WorldSpace 时 uiCamera 不能为空
        // 当 Canvas renderMode 为 RenderMode.ScreenSpaceOverlay 时 uiCamera 可以为空
        RectTransformUtility.ScreenPointToLocalPointInRectangle(rt, screenPoint, uiCamera, out globalMousePos);
        // 转换后的 globalMousePos 使用下面方法赋值
        // target 为需要使用的 UI RectTransform
        // rt 可以是 target.GetComponent<RectTransform>(), 也可以是 target.parent.GetComponent<RectTransform>()
        // target.transform.position = globalMousePos;
        return globalMousePos;
    }

    // 屏幕坐标转换为 UGUI RectTransform 的 anchoredPosition
    public static Vector2 ScreenPointToUILocalPoint(RectTransform parentRT, Vector2 screenPoint)
    {
        Vector2 localPos;
        Camera uiCamera = CameraMainControl.I.uiCamera;//.UICamera;

        RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRT, screenPoint, uiCamera, out localPos);
        return localPos;
    }

    
    public static Vector3 GetBetweenPoint(Vector3 start, Vector3 end, float percent=0.5f)
    {
        Vector3 normal = (end - start).normalized;
        float distance = Vector3.Distance(start, end);
        return normal * (distance * percent) + start;
    }
    
    public static float GetTouchRatio()
    {
#if UNITY_EDITOR
        return Input.mousePosition.x / Screen.width;
#else
        Touch theTouchs = Input.GetTouch(0);
        return theTouchs.position.x / Screen.width;
#endif
    }
    
    public static Vector3 GetTouchPos(Transform target,Camera camera)
    {
        //将 target世界坐标转换成屏幕坐标
        Vector3 targetScreenPos = camera.WorldToScreenPoint(target.position);
        //修正鼠标点的坐标
        Vector3 mousePos;
        //将 修正后的鼠标点 转换成世界坐标
#if UNITY_EDITOR
        mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPos.z);
#else
        Touch theTouchs = Input.GetTouch(0);
        mousePos = new Vector3(theTouchs.position.x,theTouchs.position.y, targetScreenPos.z);
#endif
        Vector3 mouseSToW = camera.ScreenToWorldPoint(mousePos);
        return mouseSToW;
    }
    

    
    /// <summary>
    /// 一个点绕另一个点旋转
    /// </summary>
    /// <param name="point">要旋转的点</param>
    /// <param name="pivot">中心点</param>
    /// <param name="euler">旋转的角度</param>
    /// <returns></returns>
    public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 euler)
    {
        Vector3 direction = point - pivot;
        Vector3 rotatedDirection = Quaternion.Euler(euler) * direction;
        Vector3 rotatedPoint = rotatedDirection + pivot;
        return rotatedPoint;
    }
        
        
    /// <summary>
    /// 生成一个圆形坐标
    /// </summary>
    /// <param name="forward">物体的前进方向</param>
    /// <param name="center">中心点</param>
    /// <param name="radius">半径</param>
    /// <param name="cnt">生成几个点</param>
    /// <param name="height">上升高度</param>
    /// <param name="startHeight">开始高度</param>
    /// <param name="asAngle">需要旋转的的角度</param>
    /// <param name="endAngle">结束点的角度</param>
    /// <param name="skewing">偏移的角度</param>
    /// <returns></returns>
    public static List<Vector3> GetCirclePos(Vector3 forward, Vector3 center, float radius, int cnt,float height,float startHeight,float asAngle,float endAngle,float skewing)
    {
        List<Vector3> list = new List<Vector3>();

        //减去起始高度=总的差距
        height = height - startHeight;
            
        float angles = asAngle / cnt; 
        float cityHeight = height/cnt;
        for (int i = 0; i < cnt; i++)
        {
            Vector3 pos = Quaternion.Euler(0,  (angles * i) - skewing,0) * forward.normalized * radius  + center + new Vector3(0,startHeight+(cityHeight*i),0);
            list.Add(pos);
        }
        
        //终点角度
        list.Add(Quaternion.Euler(0,  asAngle - skewing,0) * forward.normalized * radius  + center + new Vector3(0,startHeight+height,0));
        return list;
    }
    
    
    
    /// <summary>
    /// 鼠标坐标转世界坐标，拖动物体用
    /// </summary>
    /// <param name="camera">游戏视角相机</param>
    /// <param name="targetPos">目标位置</param>
    /// <param name="height">保持高度</param>
    /// <param name="skewingY">屏幕像素坐标Y轴偏移</param>
    /// <returns></returns>
    public static Vector3 GetMouseToWorldPoint(Camera camera,Vector3 targetPos,float height,float skewingY)
    {
        var dis = (camera.transform.position - targetPos).magnitude;
        var mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y + skewingY, dis);
        var pos = camera.ScreenToWorldPoint(mousePosition);
        Vector3 fwd = camera.transform.forward;
        float k = (height - pos.y) / fwd.y;
        pos += fwd * k;
        return pos;
    }
    
    
    
    /// <summary>
    /// 判断物体是否在相机范围内（准备来说，是判断一个点是否在相机范围内）
    /// </summary>
    /// <param name="testCamera">相机</param>
    /// <param name="testGo">物体</param>
    /// <returns>是否在相机范围内</returns>
    private bool IsCameraVisible(Camera testCamera,GameObject testGo)
    {
        Vector3 viewPos = testCamera.WorldToViewportPoint(testGo.transform.position);
        if (viewPos.x > 0 && viewPos.x < 1)
        {
            if (viewPos.y > 0 && viewPos.y < 1)
            {
                if (viewPos.z >= testCamera.nearClipPlane && viewPos.z <= testCamera.farClipPlane)
                {
                    return true;
                }
            }
        }
        return false;
    }
    

    
}

